﻿using System;
using System.Collections.Generic;
using System.Text;
using PCR.Base;

namespace PCR.Logic
{
    /// <summary>
    /// The root class of the whole PCR Logic module,
    /// it is a sington mode, so can only use is like this
    /// PCR.Instance.LogManger.GetLogger("Test").Info("Just a test");
    /// You should only use IRoot instance to access all the objects
    /// in the PCR logic module, all the methods and object are presented
    /// only in interface mode, because we want to hide the detailed implementation
    /// from the interface, implementation may change frequently, but interface
    /// would not change frequently
    /// /// </summary>
    public class PCRRoot
    { 
        static IRoot _root;
        
        /// <summary>
        /// Static Root constructor, we will create the global Root instance here
        /// </summary>
        static PCRRoot()
        {
            _root = new Root(DatabaseFactory.Instance);
        }
        
        /// <summary>
        /// Get the sington root instance, this is the only way to access PCR Logic object,
        /// traveling around PCR starting from here!
        /// </summary>
        public static IRoot Instance 
        {
            get { return _root; }
        }

        #region PUBLIC_METHODS
        public static string GenderString(Gender gender)
        {
            switch (gender)
            {
                case Gender.MAN: return "男";
                case Gender.WOMEN: return "女";
            }
            return "男";
        }
        public static Gender GenderValue(string gender)
        {
            if (gender == "男") return Gender.MAN;
            return Gender.WOMEN;
        }

        public static string CheckMethodString(CheckMethod method)
        {
            switch (method)
            {
                case CheckMethod.HPV: return "人乳头瘤病毒（HPV）基因检测";
                case CheckMethod.OTHER: return "其他";
            }
            return "其他";
        }
        public static CheckMethod CheckMethodValue(string method)
        {
            if (method == "人乳头瘤病毒（HPV）基因检测") return CheckMethod.HPV;
            return CheckMethod.OTHER;
        }

        public static string SampleTypeString(SampleType type)
        {
            switch (type)
            {
                case SampleType.NECKUTERUS: return "宫颈脱落细胞";
                case SampleType.SKIN: return "皮肤脱落细胞";
                case SampleType.WEASAND: return "食管脱落细胞";
                case SampleType.OTHER: return "其他";
            }
            return "其他";
        }
        public static SampleType SampleTypeValue(string type)
        {
            if (type == "宫颈脱落细胞") return SampleType.NECKUTERUS;
            if (type == "皮肤脱落细胞") return SampleType.SKIN;
            if (type == "食管脱落细胞") return SampleType.WEASAND;

            return SampleType.OTHER;
        }

        public static string SampleStateString(SampleState state)
        {
            switch (state)
            {
                case SampleState.NOTWELL: return "不合格";
                case SampleState.WELL: return "合格";
                case SampleState.UNKNOWN: return "未知";
            }
            return "未知";
        }
        public static SampleState SampleStateValue(string state)
        {
            if (state == "不合格") return SampleState.NOTWELL;
            if (state == "合格") return SampleState.WELL;

            return SampleState.UNKNOWN;
        }

        public static string VirusTypeString(Guid virusID)
        {
            if (_root == null || _root.VirusTypeManager == null) return null;
            foreach (IVirusType type in _root.VirusTypeManager.List)
            {
                if (type.ObjectID == virusID) return type.Name;
            }
            return null;
        }

        public static IVirusType VirusTypeValue(string virusName)
        {
            if (_root == null || _root.VirusTypeManager == null) return null;
            foreach (IVirusType type in _root.VirusTypeManager.List)
            {
                if (type.Name == virusName) return type;
            }
            return null;
        }

        public static string VirusDefineTypeString(VirusDefineType defineType)
        {
            switch (defineType)
            {
                case VirusDefineType.HIGHDANGER: return "高危亚型";
                case VirusDefineType.LOWDANGER: return "低危亚型";
            }
            return "未知";
        }

        public static VirusDefineType VirusDefineTypeValue(string strDefineType)
        {
            if (strDefineType == "高危亚型") return VirusDefineType.HIGHDANGER;
            if (strDefineType == "低危亚型") return VirusDefineType.LOWDANGER;

            return VirusDefineType.HIGHDANGER;
        }

        public static string GetSpitterSign()
        {
            return ",";
        }

        public static bool JudgeExponent(double exp, out string strRstText)
        {
            if (exp >= (PCRRoot.Instance.VirusTypeManager.VirusSafetyExponent * PCRRoot.Instance.VirusTypeManager.BaseCellCount))
            {
                strRstText = "阳性";
                return true;
            }

            strRstText = "阴性";
            return false;
        }

        public static string GetStdCurveHeader()
        {
            return "StdCurve";
        }

        public static string GetVirusTypeHeader()
        {
            return "VirusType";
        }

        public static string GetPatientHeader()
        {
            return "Patient";
        }

        public static string GetNothingString()
        {
            return "无";
        }

        public static IList<IPatientReport> SearchReport(string strName, DateTime dtReportDateFrom, DateTime dtReportDateTo, DateTime dtCheckDateFrom, DateTime dtCheckDateTo, UInt32 uiAgeFrom, UInt32 uiAgeTo, IList<Gender> listGender, IList<Guid> listVirusType)
        {
            if (_root == null || _root.PatientManager == null) return null;

            IList<IPatientReport> list = new List<IPatientReport>();
            foreach (IPatientReport report in _root.PatientManager.List)
            {
                if (report.ReportDate < dtReportDateFrom || report.ReportDate > dtReportDateTo) continue;
                if (report.CheckDate < dtCheckDateFrom || report.ReportDate > dtCheckDateTo) continue;
                if (report.Age < uiAgeFrom || report.Age > uiAgeTo) continue;
                if (!listGender.Contains(report.Gender)) continue;

                if (strName != null && strName.Length > 0)
                {
                    if (strName != report.Name) continue;
                }

                bool bToAdd = false;
                foreach (IPatientVirus virus in report.PatientVirusList)
                {
                    if (listVirusType.Contains(virus.VirusTypeID))
                    {
                        bToAdd = true;
                        break;
                    }
                }

                if (bToAdd) list.Add(report);
            }

            return list;
        }
        public static IList<IPatientReport> SearchAllReport()
        {
            if (_root == null || _root.PatientManager == null) return null;
            return _root.PatientManager.List;           
        }

        #endregion
    }
    
    /// <summary>
    /// Root class, contain all the logic interfaces
    /// </summary>
    internal class Root : IRoot
    {
        /// <summary>
        /// Internal members
        /// </summary>
        IPatientManager _patientManager = null;
        ILogManager _logManager = null;
        IPrivilegeManager _privilegeManager = null;
        IConfigManager _configManager = null;
        IStdCurveManager _stdCurveManager = null;
        IVirusTypeManager _virusTypeManager = null;
        IIOManager _ioManager = null;
        ICalculator _calculator = null;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="database">The database interface</param>
        public Root(IDatabase database)
        {
            // Create a instance for each manager type
            this._patientManager = new PatientManager(database);
            this._virusTypeManager = new VirusTypeManager(database);
            this._privilegeManager = new PrivilegeManager(database);
            this._stdCurveManager = new StdCurveManager(database);
            this._configManager = new ConfigManager(database);
            this._ioManager = new IOManager(); 
            this._calculator = new Calculator();
        }

        /// <summary>
        /// Get the log interface
        /// </summary>
        public ILogManager LogManager 
        {
            get { return this._logManager; }
        }

        /// <summary>
        /// Get the privilege manager interface
        /// </summary>
        public IPrivilegeManager PrivilegeManager 
        {
            get { return this._privilegeManager; }
        }
        
        /// <summary>
        /// Get the configuration manager interface
        /// </summary>
        public IConfigManager ConfigManager 
        {
            get { return this._configManager; }
        }

        /// <summary>
        /// Get the standard curve manager interface
        /// </summary>
        public IStdCurveManager StdCurveManager 
        {
            get { return this._stdCurveManager; }
        }

        /// <summary>
        /// Get the virus type manager interface
        /// </summary>
        public IVirusTypeManager VirusTypeManager 
        { 
            get { return this._virusTypeManager; }
        }

        /// <summary>
        /// Get the patient manager interface
        /// </summary>
        public IPatientManager PatientManager 
        {
            get { return this._patientManager; } 
        }
        
        /// <summary>
        /// Get the IOManager interface
        /// </summary>
        public IIOManager IOManager 
        {
            get { return this._ioManager; }
        }  
        
        /// <summary>
        /// Get the calculator interface
        /// </summary>
        public ICalculator Calculator 
        {
            get { return this._calculator; }
        }

        /// <summary>
        /// Create the specified object by object type
        /// </summary>
        public object CreateObject(ObjectType objType)
        {
            return ObjectFactory.CreateObject(objType);
        }
    }
    
}
